/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 
 * @author JAD!
 */
public class Server extends Thread {

	java.net.ServerSocket sock = null;
	ArrayList<Oner_serv> usersSock = new ArrayList<Oner_serv>();
	int num = 0;
	boolean stat_suspend = false;
	int port;

	/**
	 * @param args
	 *            the command line arguments
	 */
	public Server(int port) {

		super();
		this.port = port;

	}

	public void socketStarter() {
		this.start();

		while (true) {
			this.yield();
			try {
				sleep(2000);
			} catch (InterruptedException ex) {
				Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
						null, ex);
			}
			for (int i = 0; i < usersSock.size(); i++) {

				if (usersSock.get(i).getState() == Thread.State.TERMINATED) {
					System.out.println("Client " + usersSock.get(i).name
							+ " deleted.");
					usersSock.remove(i);

				}
				/*
				 * if (!usersSock.get(i).isConnected()) {
				 * System.out.println("Client " + i + " go away!"); try {
				 * usersSock.get(i).close(); } catch (IOException ex) {
				 * Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
				 * null, ex); } usersSock.remove(i); break; }
				 * 
				 * try {
				 * 
				 * // String.valueOf(data); if
				 * (usersSock.get(i).getInputStream().available() != 0) {
				 * System.out.println(new java.io.BufferedReader(new
				 * java.io.InputStreamReader
				 * (usersSock.get(i).getInputStream())).readLine() ); } } catch
				 * (IOException ex) {
				 * Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
				 * null, ex); }
				 */}
		}
	}

	public boolean getStateServer() {
		return true;
	}

	public void run() {
		if (sock == null)
			try {
				sock = new java.net.ServerSocket(port);

			} catch (IOException ex) {
				System.out
						.println("Не удалось, возможно не верный порт");
			}
		Socket cl = null;
		while (true) {

			if (usersSock.size() == 40) {
				this.yield();
				try {
					sleep(1000);
				} catch (InterruptedException ex) {
					Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
							null, ex);
				}
				continue;
			}

			try {
				cl = sock.accept();
			} catch (IOException ex) {
				Logger.getLogger(Server.class.getName()).log(Level.SEVERE,
						null, ex);
			}
			System.out.println("Server say: Client " + String.valueOf(num)
					+ " connected!");

			Oner_serv ty = new Oner_serv(cl, String.valueOf(num));
			usersSock.add(ty);
			num++;
			ty.start();

		}

	}

	public void suspend_Serv() {
		try {
			sock.close();
		} catch (IOException ex) {
			System.out.println("Socket_Server already closed");
		}
		this.suspend();
	}

}

class Oner_serv extends Thread {

	Socket sock;
	java.io.BufferedReader in;
	java.io.PrintWriter out;
	Long time = System.currentTimeMillis();
	public String name;

	public Oner_serv(Socket cl, String name) {
		super();
		this.name = name;
		sock = cl;
		try {
			in = new java.io.BufferedReader(new java.io.InputStreamReader(sock
					.getInputStream()));
			out = new java.io.PrintWriter(new java.io.BufferedWriter(
					new java.io.OutputStreamWriter(sock.getOutputStream())),
					true);
		} catch (IOException ex) {
			finalize();
		}

	}

	public void run() {

		while (true) {

			String geted = "";

			try {
				if (in.ready())
					while ((geted = in.readLine()) != null) {
						String tock = geted;
						// java.util.StringTokenizer stk=new
						// java.util.StringTokenizer(geted);
						// while (stk.hasMoreTokens())
						// {
						// String tock=stk.nextToken();
						if (tock != "END") {
							if (tock.equals("name?"))
								out.println(name);
							else
								out.println(String.valueOf(System
										.currentTimeMillis()));
							// -----------------------------------------------------------

							time = System.currentTimeMillis();
							System.out.println("Server recived say: Client "
									+ name + " sended: " + tock);// +" "
																	// +String.valueOf(System.currentTimeMillis()-Long.parseLong(tock)));
						} else
							finalize();
						// }

						while (!in.ready()) {
							try {
								if (System.currentTimeMillis() - time > 7000) {
									System.out.println("Server say: Client "
											+ name + " go out!");
									finalize();
								} else
									sleep(300);
							} catch (InterruptedException ex) {
								finalize();
							}
						}

					}
				else
					try {
						sleep(100);
					} catch (InterruptedException ex) {
						Logger.getLogger(Oner_serv.class.getName()).log(
								Level.SEVERE, null, ex);
					}
			} catch (IOException ex) {
				finalize();
			}
		}

	}

	protected void finalize() {
		try {
			in.close();
			out.close();
			sock.close();
		} catch (IOException ex) {
			Logger.getLogger(Oner_serv.class.getName()).log(Level.SEVERE, null,
					ex);
		}
		System.out.println("Server say: Servers thread for client " + name
				+ " stopped!");
		this.stop();
	}

}